//
//  PhotoClipScrollView.swift
//  JJImagePicker
//
//  Created by 李加建 on 2021/6/1.
//

import UIKit

class PhotoClipScrollView: UIScrollView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    var canclip: Bool = true

    @available(*, unavailable)
    required init?(coder _: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var imageView: UIImageView = {
        let lazy = UIImageView(frame: .zero)
        return lazy
    }()

    func setup() {
        delegate = self
        minimumZoomScale = 1
        maximumZoomScale = 3
        showsVerticalScrollIndicator = false
        showsHorizontalScrollIndicator = false
        addSubview(imageView)

        contentInsetAdjustmentBehavior = .never
    }

    var currentImage: UIImage? {
        didSet {
            imageView.image = currentImage
            guard let image = currentImage else { return }
            updateRect(image: image)
        }
    }

    var pointY: CGFloat {
        let height: CGFloat = frame.height
        let width: CGFloat = frame.width - 40
        return (height - width)
    }

    var pointX: CGFloat {
        40
    }

    func updateRect(image: UIImage) {
        let width = frame.width - 40
        let scale: CGFloat = image.size.height / image.size.width

        if scale > 1 {
            let height2: CGFloat = width * scale
            contentSize = CGSize(width: width + pointX, height: height2 + pointY)
            imageView.frame = CGRect(x: 20, y: 0, width: width, height: height2)
            imageView.center = CGPoint(x: contentSize.width / 2, y: contentSize.height / 2)
            contentOffset = CGPoint(x: 0, y: (height2 - width) / 2)

        } else {
            let width2: CGFloat = width / scale
            contentSize = CGSize(width: width2 + pointX, height: width + pointY)
            imageView.frame = CGRect(x: 20, y: 0, width: width2, height: width)
            imageView.center = CGPoint(x: contentSize.width / 2, y: contentSize.height / 2)
            contentOffset = CGPoint(x: (width2 - width) / 2, y: 0)
        }
    }
}

extension PhotoClipScrollView: UIScrollViewDelegate {
    func viewForZooming(in _: UIScrollView) -> UIView? {
        imageView
    }

    func scrollViewDidZoom(_: UIScrollView) {
        contentSize = CGSize(width: contentSize.width + pointX, height: imageView.frame.size.height + pointY)
        let offsetX = bounds.size.width > contentSize.width ? (bounds.size.width - contentSize.width) * 0.5 : 0.0
        let offsetY = bounds.size.height > contentSize.height ? (bounds.size.height - contentSize.height) * 0.5 : 0.0
        imageView.center = CGPoint(x: contentSize.width * 0.5 + offsetX, y: contentSize.height * 0.5 + offsetY)
    }

    func scrollViewWillBeginDragging(_: UIScrollView) {
        canclip = false
    }

    func scrollViewDidEndDragging(_: UIScrollView, willDecelerate _: Bool) {
        canclip = true
    }

    func scrollViewDidEndZooming(_: UIScrollView, with _: UIView?, atScale _: CGFloat) {
        canclip = true
    }

    func scrollViewWillBeginDecelerating(_: UIScrollView) {
        canclip = false
    }

    func scrollViewDidEndDecelerating(_: UIScrollView) {
        canclip = true
    }

    @discardableResult
    func clipperImage() -> UIImage? {
        guard let image = imageView.image else { return nil }
        let imageScale: CGFloat = image.size.width / imageView.frame.width
        let cropX: CGFloat = contentOffset.x * imageScale
        let cropY: CGFloat = contentOffset.y * imageScale
        let cropWidth: CGFloat = (frame.width - 40) * imageScale
        let cropRect = CGRect(x: cropX, y: cropY, width: cropWidth, height: cropWidth)
//        print("\(contentOffset) \(cropRect)")
        let sourceImageRef = image.cgImage
        guard let newImageRef = sourceImageRef?.cropping(to: cropRect) else { return nil }
//        return UIImage(cgImage: newImageRef)
        return UIImage(cgImage: newImageRef, scale: 1, orientation: image.imageOrientation)
    }
}
